//
//  MainViewController.swift
//  weibo
//
//  Created by Fly on 2017/12/11.
//  Copyright © 2017年 Fly. All rights reserved.
//

import UIKit
import SVProgressHUD

class MainViewController: UITabBarController {

    // MARK: 懒加载属性前加修饰符“private”，在扩展(exytension)中无法使用，只能在class中使用
//    private lazy var composeBtn: UIButton = UIButton()
    
    // MARK: swift的懒加载相当于闭包，不能使用“self.”
    lazy var composeBtn: UIButton = UIButton()
    
    fileprivate var timer: Timer?
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        setupChildControllers()

        delegate = self
        
        // 注册通知
        NotificationCenter.default.addObserver(self, selector: #selector(userLogin(n:)), name: NSNotification.Name(rawValue: UserShouldLogonNotification), object: nil)
        
        setupNewFeature()
        
    }
    
    deinit {
        
        timer?.invalidate()
        
        NotificationCenter.default.removeObserver(self)
        
    }
    
    /// 监听方法
    ///
    /// - Parameter n: 传值
    @objc private func userLogin(n: Notification) {
        
        print("用户登录通知 \(n)")
        
        var afterTime = DispatchTime.now()
        
        // 判断 n.obect 是否有值，如果有值，提示用户重新登录
        if n.object != nil {
            
            SVProgressHUD.setDefaultMaskType(.gradient)
            
            SVProgressHUD.showInfo(withStatus: "用户登录已经超时，需要重新登录")
            
            afterTime = DispatchTime.now() + 2
            
        }
        
        DispatchQueue.main.asyncAfter(deadline: afterTime) {
            
            SVProgressHUD.setDefaultMaskType(.clear)
            
            let vc = OAuthViewController()
            
            let navigation = UINavigationController(rootViewController: vc)
            
            self.present(navigation, animated: true, completion: nil)
            
        }

    }
    
    // MARK: 设备支持方向，竖屏
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
        
        return .portrait
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
//    @objc func composeBtnClicked() {
//        
//        print("中间加号按钮")
//        
//    }

}

extension MainViewController {
    
    // MARK:扩展(extension)中的方法加了修饰符private，在class中无法使用，只能在extension中使用
    func setupChildControllers() {
        
        // 从沙盒中获取json文件路径
        let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        
        let jsonPath = (docDir as NSString).appendingPathComponent("main.json")
        
        var data = NSData(contentsOfFile: jsonPath)
        
        if data == nil {// 如果沙盒中没有json文件则加载bundle中的json文件
            
            let path = Bundle.main.path(forResource: "main.json", ofType: nil)
            
            data = NSData(contentsOfFile: path!)
            
        }
        
        // 从bundle加载配置的json
        // throw 抛出异常 处理方式
        // 1.推荐使用 try? 如果解析成功就有值，否则为nil
        // 2.不推荐使用 try! 如果解析成功就有值，否则奔溃
        // 3. do {} catch {} 处理异常 能够接收错误并输出错误，但是语法结构复杂，一旦不平衡，就会出现内存泄漏 
//        do {
//            
//            let x = try JSONSerialization.jsonObject(with: data! as Data, options: [])
//        
//        } catch {
//            print(error)
//        }
        guard let array = try? JSONSerialization.jsonObject(with: data! as Data, options: []) as? [[String: Any]]
            else {
                return
        }
        
        // 1.获取文件路径  2.加载NSDate  3.反序列化转换成数组
//        guard let path = Bundle.main.path(forResource: "main.json", ofType: nil),
//            let data = NSData(contentsOfFile: path),
//            let array = try? JSONSerialization.jsonObject(with: data as Data, options: []) as? [[String: Any]]
//            else {
//            return
//        }
        
//        let arr = NSArray(contentsOfFile: path) as? [[String: Any]]
        
//        let array: [[String: Any]] = [
//            ["clsName": "HomeViewController", "title": "首页", "imageName": "home",
//             "visitorDic": ["imageName": "", "message": "关注Swift的测试demo,关注Swift的测试demo,关注Swift的测试demo,关注Swift的测试demo,关注Swift的测试demo"]],
//            
//            ["clsName": "MessageViewController", "title": "消息", "imageName": "message",
//             "visitorDic": ["imageName": "bigMessage", "message": "登录后别人发给你的信息，评论你的微博，都会显示在这里"]],
//            
//            ["clsName": "UIViewController"],
//            
//            ["clsName": "DiscoverViewController", "title": "发现", "imageName": "discover",
//             "visitorDic": ["imageName": "bigDiscover", "message": "登录后最新最热的微博尽在掌握，走过路过不错过 "]],
//            
//            ["clsName": "ProfileViewController", "title": "我", "imageName": "me",
//             "visitorDic": ["imageName": "bigMe", "message": "登录后将有更多的人能欣赏到你的精彩照片"]]
//        ]
        
        // 将数组写成plist文件存在电脑桌面(NSString,NSArray,NSDictionary,NSData)
//        (array as NSArray).write(toFile: "/Users/joe/Desktop/demo.plist", atomically: true)
        
        // 数组 -> json 序列化
        // prettyPrinted Json的排版格式
//        let data = try! JSONSerialization.data(withJSONObject: array, options: [.prettyPrinted])
        // 将data写成json文件存在电脑桌面
//        (data as! NSData).write(toFile: "/Users/joe/Desktop/demo.plist", atomically: true)
        
        var arrayVC = [UIViewController]()
        
        for dict in array! {
            
            arrayVC.append(controller(dict: dict))
            
        }
        
        viewControllers = arrayVC
        
        setupComposeBtn()
        
        NetworkManager.networkManager.userLogon ? setupTimer() : ()
        
    }
    
    // 中间加号按钮
    private func setupComposeBtn() {
        
        composeBtn.setImage(#imageLiteral(resourceName: "addBtn"), for: .normal)
        
        composeBtn.setImage(#imageLiteral(resourceName: "addBtn_heightlight"), for: .highlighted)
//        composeBtn.setBackgroundImage(#imageLiteral(resourceName: "addBtn"), for: UIControlState(rawValue: 0))
        tabBar.addSubview(composeBtn)
        
        let count = CGFloat(childViewControllers.count)
        
//        let w = tabBar.bounds.width / count - 1
        let w = tabBar.bounds.width / count
        
//        composeBtn.frame = CGRect(x: 2.2 * w, y: 5, width: 50, height: 40)
        
        composeBtn.frame = tabBar.bounds.insetBy(dx: 2 * w, dy: 0)
        
        // MARK: 给按钮添加触发事件的代码写在extension中，则触发方法写在extension中可以加private修饰符，若触发方法写在class中，就不能加private修饰符(会找不到触发方法)
        composeBtn.addTarget(self, action: #selector(composeBtnClicked), for: .touchUpInside)
        
    }
    
    // 中间加号按钮点击方法
    @objc private func composeBtnClicked() {
        
        let vc = UIViewController()
        
        vc.title = "write"
        
        vc.view.backgroundColor = UIColor.randomColor
        
        let nav = UINavigationController(rootViewController: vc)
        
        nav.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(back))
        
        present(nav, animated: true, completion: nil)
        
    
    }
    
    @objc private func back() {
        
        dismiss(animated: true, completion: nil)
        
    }
    
    private func controller(dict: [String: Any]) -> UIViewController {
        
        guard let clsName = dict["clsName"] as? String,
            let title = dict["title"] as? String,
            let imageName = dict["imageName"] as? String,
            let visitorDic = dict["visitorDic"] as? [String: String],
            let cls = NSClassFromString(Bundle.main.namespace + "." + clsName) as? BaseViewController.Type
        
        else {
            return UIViewController()
        }
        
        let vc = cls.init()
        
        vc.title = title
        
        vc.tabBarItem.image = UIImage(named: imageName)
        
        vc.tabBarItem.selectedImage = UIImage(named: imageName + "_sel")?.withRenderingMode(.alwaysOriginal)
        
        vc.visitorDic = visitorDic
        
        // 设置tabbar按钮文本颜色
        vc.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.black], for: .highlighted)
        
        // 设置tabbar按钮文本字体大小，系统默认12.0
        vc.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.systemFont(ofSize: 12.0)], for: UIControlState(rawValue: 0))
        
        let nav = NavigationController(rootViewController: vc)
        
        return nav
        
    }
    
    /// 定义时钟,定期检查未读微博数量
    private func setupTimer() {
        
        timer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
        
    }
    
    @objc private func updateTimer() {
        
        // 如果未登录则不请求检测未读微博数量
//        if !NetworkManager.networkManager.userLogon {
//            return
//        }
        
        // 测试
        NetworkManager.networkManager.unReadCount { (count) in
            
            print("有\(count)条新微博")
            
            // 设置 tabarItem “首页” 的 badgeNumber
            let str = count > 0 ? "\(count)" : nil
            
            self.tabBar.items?[0].badgeValue = str
            
            // 设置 APP 的 badgeNumber iOS8以后要用户授权
            UIApplication.shared.applicationIconBadgeNumber = count
            
        }
        
    }
    
}

// MARK: - UITabBarControllerDelegate
extension MainViewController: UITabBarControllerDelegate {
    
    /// 将要选择tabBarItem
    ///
    /// - Parameters:
    ///   - tabBarController: TabBarController
    ///   - viewController: 目标控制器
    /// - Returns: 是否切换
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        
//        print("将要切换到 \(viewController)")
        
        // 获取控制器数组中的索引
        let idx = (childViewControllers as NSArray).index(of: viewController)
        
        if selectedIndex == 0 && selectedIndex == idx {
            
            // 让表格滚动到顶部
            let nav = childViewControllers[0] as! UINavigationController
            let vc = nav.childViewControllers[0] as! HomeViewController
            vc.tableView?.setContentOffset(CGPoint(x: 0, y: -64), animated: true)

            // 刷新数据 - 增加延时，保证表格先滚动到顶部再刷新
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {

                vc.loadData()

            }
            
            // 清除 badgeNumber（刷新成功，才清除）
            vc.tabBarItem.badgeValue = nil
            
            UIApplication.shared.applicationIconBadgeNumber = 0
        }
        
        
        // 判断目标控制器是否是UIViewController
        let change: Bool = !viewController.isMember(of: UIViewController.self)
        
        return change
        
    }
    
}

// MARK: - 新特性视图处理
extension MainViewController {
    
    /// 设置新特性视图
    fileprivate  func setupNewFeature() {
        
        // 判断是否登录
        if !NetworkManager.networkManager.userLogon {
            return
        }
        
        // 检查版本是否更新
        
        // 更新，显示新特性，否则显示欢迎页
        let aView = isNewFeature ? NewFeatureView.newFeatureView() : WelcomeView.welcomeView()
        
        // 添加视图 xib对应的视图设置了frame
//        aView.frame = view.bounds
        
        view.addSubview(aView)
    }
    
    /**
     在 App Store 中，每次升级应用程序，版本号都会增加（不能递减）
     组成：主版本号.次版本号.修订版本号
     主版本号：大改，用户需要做大的适应
     次版本号：小改，某些函数和方法的使用或参数有变化
     修订版本号：框架/程序内部bug修订，不对用户造成影响
     
     */
    
    //extension 中可以有计算型属性，不会占用储存空间。 构造函数给属性分配空间
    private var isNewFeature: Bool {
        
        // 1.获取当前版本号
//        print(Bundle.main.infoDictionary)
        let  currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
        
        // 2.取保存在 document （iTunes备份）[最理想是保存在用户偏好中 - NSUserdefault]中的之前的版本号
        let path = "version".documentAppendingPathComponent()
        
        let sandBoxVersion = try? String(contentsOfFile: path) ?? ""
        
        // 3.将当前版本号保存在沙盒中
        try? currentVersion.write(toFile: path, atomically: true, encoding: .utf8)
        
        // 4.比较两个版本号是否一致
        let versionIsSame = currentVersion != sandBoxVersion //欢迎页
//        let versionIsSame = currentVersion == sandBoxVersion //新特性

        return versionIsSame
        
    }
    
}
